// use std::{sync::Arc, fs::{create_dir_all, File}, path::PathBuf};
// use crate::prisma::{self, PrismaClient};

// pub async fn load_and_migrate(db_url: PathBuf) -> Arc<PrismaClient> {
//     let db_dir = db_url.parent().unwrap();
//     if !db_dir.exists() {
//         create_dir_all(db_dir).unwrap()
//     }

//     if !db_url.exists() {
//         File::create(db_url.clone()).unwrap();
//     }

//     let db_url = format!("file:{}", db_url.to_str().unwrap());

//     let client = prisma::new_client_with_url(&db_url).await.unwrap();

//     #[cfg(debug_assertions)]
//     client._db_push().await.unwrap();

//     #[cfg(not(debug_assertions))]
//     client._migrate_deploy().await.unwrap();

//     Arc::new(client)
// }


use crate::prisma::{self, PrismaClient};
use prisma_client_rust::{migrations::*, NewClientError};
use thiserror::Error;

#[derive(Error, Debug)]
pub enum MigrationError {
	#[error("An error occurred while initialising a new database connection: {0}")]
	NewClient(#[from] Box<NewClientError>),
	#[cfg(debug_assertions)]
	#[error("An error occurred during migration: {0}")]
	MigrateFailed(#[from] DbPushError),
	#[cfg(not(debug_assertions))]
	#[error("An error occurred during migration: {0}")]
	MigrateFailed(#[from] MigrateDeployError),
}

/// load_and_migrate will load the database from the given path and migrate it to the latest version of the schema.
pub async fn load_and_migrate(db_url: &str) -> Result<PrismaClient, MigrationError> {
	let client = prisma::new_client_with_url(db_url)
		.await
		.map_err(Box::new)?;

	#[cfg(debug_assertions)]
	{
		let mut builder = client._db_push();

		if std::env::var("SD_FORCE_RESET_DB")
			.map(|v| v == "true")
			.unwrap_or(false)
		{
			builder = builder.accept_data_loss().force_reset();
		}

		builder.await?;
	}

	#[cfg(not(debug_assertions))]
	client._migrate_deploy().await.unwrap();

	Ok(client)
}

